<template>
  <div class="my-chat-container">
    <!-- 侧边栏 -->
    <div class="side-bar-container">
      <!-- 模型信息 -->
      <div class="model-info-wrapper">
        <div class="model-avatar">
          <img :src="chatModel.avatar" alt="" />
        </div>
        <div class="model-name" :class="getModelNameClass">{{ chatModel.name }}</div>
        <div class="model-author-wrapper">
          <div class="author-avatar">
            <img src="~/assets/role/bolatu_avatar.png" alt="" />
          </div>
          <span>理想国</span>
          <SafetyCertificateFilled class style="color: #1677ff" />
        </div>
        <div class="model-tag-wrapper">
          <div class="tag-item">官方</div>
          <div class="tag-item">推荐</div>
          <div class="tag-item">不错</div>
        </div>
        <div class="model-desc">
          {{ chatModel.desc }}
        </div>
        <div class="model-clear-btn">
          <a-button @click="handleClearChat" :disabled="chatRecordList.length === 0"> 清空对话 </a-button>
        </div>
      </div>
      <!-- 模型列表 -->
      <div class="recent-model-list-wrapper">
        <div class="recent-model-list-title">最近聊天模型</div>
        <div class="recent-model-list">
          <div
            class="recent-model-item"
            v-for="model in modelList"
            :key="model.id"
            :class="{ active: model.id === chatModel.id }"
            @click="handleSwitchModel(model)"
          >
            <div class="recent-model-avatar">
              <img :src="model.avatar" alt="" />
            </div>
            <div class="recent-model-name">{{ model.name }}</div>
          </div>
        </div>
      </div>
    </div>

    <div class="my-chat-wrapper">
      <!-- 对话区域（缺省） -->
      <div v-if="chatRecordList.length === 0" class="no-chat-container">
        <!-- 加载状态显示骨架屏 -->
        <template v-if="isLoading">
          <div class="no-chat-avatar">
            <a-skeleton-avatar :size="120" active shape="square" />
          </div>
          <div class="no-chat-name">
            <a-skeleton active :paragraph="{ rows: 1, width: '200px' }" :title="false" />
          </div>
          <div class="no-chat-desc">
            <a-skeleton active :paragraph="{ rows: 2, width: ['300px', '250px'] }" :title="false" />
          </div>
          <div class="no-chat-question-wrapper">
            <div class="no-chat-question-title">你可以这样问我：</div>
            <div class="no-chat-question-item">
              <a-skeleton active :paragraph="{ rows: 1, width: '200px' }" :title="false" />
            </div>
            <div class="no-chat-question-item">
              <a-skeleton active :paragraph="{ rows: 1, width: '180px' }" :title="false" />
            </div>
            <div class="no-chat-question-item">
              <a-skeleton active :paragraph="{ rows: 1, width: '220px' }" :title="false" />
            </div>
          </div>
        </template>
        <!-- 非加载状态显示正常内容 -->
        <template v-else>
          <div class="no-chat-avatar">
            <img :src="chatModel.avatar" alt="" />
          </div>
          <div class="no-chat-name">{{ chatModel.name }}</div>
          <div class="no-chat-desc">
            {{ chatModel.description }}
          </div>
          <div class="no-chat-question-wrapper">
            <div class="no-chat-question-title">你可以这样问我：</div>
            <div
              class="no-chat-question-item"
              @click="handleQuickTips(chatModel.question1)"
            >
              {{ chatModel.question1 }}
            </div>
            <div
              class="no-chat-question-item"
              @click="handleQuickTips(chatModel.question2)"
            >
              {{ chatModel.question2 }}
            </div>
            <div
              class="no-chat-question-item"
              @click="handleQuickTips(chatModel.question3)"
            >
              {{ chatModel.question3 }}
            </div>
          </div>
        </template>
      </div>

      <!-- 对话区域 -->
      <div v-else class="chat-container">
        <div
          v-for="record in chatRecordList"
          :key="record.id"
          :class="
            record.role === 'user' ? 'user-chat-item' : 'assistant-chat-item'
          "
        >
          <div class="chat-avatar">
            <img
              :src="
                record.role === 'user' ? userInfo.avatar : chatModel.avatar
              "
              alt=""
            />
          </div>
          <div class="chat-content-wrapper">
            <div class="chat-name">{{ record.role === 'user' ? userInfo.name : chatModel.name }}</div>
            <div class="chat-content">
              <template v-if="!record.content && record.role == 'assistant'">
                <LoadingOutlined />
              </template>
              <template v-else>
                <template v-if="record.type == 'audio'">
                  <span
                    class="audio-wrapper"
                    :style="playingVoiceId == record.id ? 'color: #1677ff' : ''"
                    @click="
                      playingVoiceId == record.id
                        ? handleStopVoice()
                        : handlePlayVoice(record.content, record.id)
                    "
                    ><span class="audio-img"
                      ><img
                        :src="
                          playingVoiceId === record.id ? wave_playing : wave
                        "
                        alt=""
                      /> </span
                    >{{ record.duration }}s</span
                  >
                </template>
                <template v-else>
                  {{ record.content }}
                </template>
              </template>
            </div>
          </div>
        </div>
      </div>
      <!-- 输入框 -->
      <div class="user-input-container">
        <a-textarea
          v-model:value="userInput"
          placeholder="请输入"
          :autoSize="{ minRows: 1, maxRows: 6 }"
          :maxlength="1000"
          @keydown="handleKeyDown"
        />
        <div class="tools-bar-wrapper">
          <a-tooltip
            :title="
              isRecording
                ? '停止录音'
                : isClient
                ? '语音输入'
                : '语音输入不可用'
            "
          >
            <a-button
              shape="circle"
              :icon="h(AudioFilled)"
              :type="isRecording ? 'primary' : 'default'"
              :disabled="!isClient"
              @click="handleVoiceInputClick"
            ></a-button>
          </a-tooltip>
          <a-tooltip title="发送">
            <a-button
              type="primary"
              shape="circle"
              :icon="h(ArrowUpOutlined)"
              :loading="sendBtnLoading"
              @click="handleSendMessage"
            ></a-button>
          </a-tooltip>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
// ------------ import ------------
import { reactive, ref, onMounted, computed } from "vue";
import {
  ArrowUpOutlined,
  AudioFilled,
  SafetyCertificateFilled,
  LoadingOutlined,
} from "@ant-design/icons-vue";
import { chatStream } from "~/api/fetchEveneSource";
import { getCharacters, getCharacterDetail, textToSpeech, speechToText } from "~/api/chat";
import bolatuAvatar from "~/assets/role/bolatu_avatar.png";
import kongziAvatar from "~/assets/role/kongzi_avatar.png";
import wave from "~/assets/wave.svg";
import wave_playing from "~/assets/wave_playing.svg";
import { fetchEventSource } from "@microsoft/fetch-event-source";
import { message, Modal } from "ant-design-vue";
// ------------ data ------------
const chatModel = ref({
  id: 1,
  name: "",
  avatar: "",
});
const userInput = ref("");

const modelList = reactive([]);
// 对话记录
// const chatRecordList = ref([]);
const chatRecordList = reactive([]);
// 用户信息
const userInfo = ref({
  id: 1,
  name: "理想国",
  avatar: bolatuAvatar,
});
// 发送按钮loading状态
const sendBtnLoading = ref(false);

const playingVoiceId = ref("");

// 用于存储当前音频上下文和音频源（响应式）
const currentAudioContext = ref(null);
const currentAudioSource = ref(null);

// 语音输入相关状态
const isRecording = ref(false);
const mediaRecorder = ref(null);
const audioChunks = ref([]);

// 客户端环境检查
const isClient = ref(false);

// 加载状态
const isLoading = ref(true);

// 计算属性：根据模型名称长度返回样式类
const getModelNameClass = computed(() => {
  if (!chatModel.value || !chatModel.value.name) return '';
  const nameLength = chatModel.value.name.length;
  
  if (nameLength > 10) {
    return 'model-name-long';
  } else if (nameLength > 8) {
    return 'model-name-medium';
  }
  return '';
});

// ------------ function ------------
// 初始化方法
const handleInit = async () => {
  isLoading.value = true;
  await handleGetCharacters();
  await handleGetChatModel();
  isLoading.value = false;
};

// 获取角色详情
const handleGetChatModel = async () => {
  const route = useRoute();
  const characterId = route.query.id;
  if (characterId) {
    const res = await getCharacterDetail(characterId);
    chatModel.value = res.data;
  }
}

// 获取所有角色信息
const handleGetCharacters = async () => {
  const res = await getCharacters();
  modelList.push(...res.data);
  if (!chatModel.value.name && modelList.length > 0) {
    handleSwitchModel(modelList[0]);
  }
};

// 切换模型
const handleSwitchModel = (model) => {
  isLoading.value = true;
  chatModel.value = model;
  // 清空对话记录
  chatRecordList.length = 0;
  
  // 短暂显示加载状态后恢复
  setTimeout(() => {
    isLoading.value = false;
    
    // 滚动到选中的模型项
    const activeModelElement = document.querySelector('.recent-model-item.active');
    const modelListContainer = document.querySelector('.recent-model-list');
    
    if (activeModelElement && modelListContainer) {
      // 计算元素在容器内的相对位置
      const containerRect = modelListContainer.getBoundingClientRect();
      const elementRect = activeModelElement.getBoundingClientRect();
      
      // 计算需要滚动的距离
      const scrollTop = elementRect.top - containerRect.top + modelListContainer.scrollTop;
      
      // 平滑滚动到目标位置
      modelListContainer.scrollTo({
        top: scrollTop,
        behavior: 'smooth'
      });
    }
  }, 100);
};

// 键盘事件处理
const handleKeyDown = (event) => {
  // 如果按下回车键且没有按下Shift键，则发送消息
  if (event.key === "Enter" && !event.shiftKey) {
    event.preventDefault(); // 阻止默认的换行行为
    handleSendMessage(); // 调用发送消息函数
  }
  // 如果按下Shift+回车，则允许默认的换行行为（不做任何处理）
};

// 发送消息
const handleSendMessage = async () => {
  if (!userInput.value.trim()) {
    return;
  }
  let userInputValue = userInput.value;
  userInput.value = "";

  // 加入用户记录
  chatRecordList.push({
    role: "user",
    content: userInputValue,
  });
  chatRecordList.push({
    role: "assistant",
    content: "",
  });
  // 发送按钮loading状态
  sendBtnLoading.value = true;

  await chatStream(
    `/api/voice-chat/text-stream/${chatModel.value.id}`,
    { message: userInputValue },
    async (event) => {
      try {
        // 从事件数据中提取实际的消息数据，通过分割字符串获取 "data: " 之后的内容
        console.log(event.data);
        const dataStr = event.data.split("data: ")[1];
        // 将提取出的字符串解析为 JSON 对象
        const data = JSON.parse(dataStr);

        // 检查数据中的 content 是否为 "[STREAM_COMPLETE]"，若是则表示数据流传输完成
        if (data?.content == "[STREAM_COMPLETE]") {
          handleGenerateVoice(
            chatRecordList[chatRecordList.length - 1].content
          );

          sendBtnLoading.value = false;
        } else {
          // 若数据流未完成，将接收到的内容追加到最后一条助手对话记录中
          chatRecordList[chatRecordList.length - 1].content += data.content;
        }
      } catch (error) {
        console.log(error);
      }
    }
  );
};

// 生成语音
const handleGenerateVoice = async (content) => {
  chatRecordList.push({
    role: "assistant",
    type: "audio",
    id: Date.now(),
  });

  const res = await textToSpeech(chatModel.value.id, { text: content });
  const voice = res.data.data;

  // 播放Base64格式的wav音频
  if (voice) {
    try {
      // 将Base64转换为ArrayBuffer
      const binaryString = atob(voice);
      const bytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
      }

      // 创建AudioContext并解码音频数据
      const audioContext = new (window.AudioContext ||
        window.webkitAudioContext)();
      audioContext.decodeAudioData(bytes.buffer, (buffer) => {
        // 获取音频时间（秒）
        const duration = buffer.duration;
        // 可以在这里使用duration变量，例如显示在UI上
        chatRecordList[chatRecordList.length - 1].duration =
          Math.ceil(duration);
        chatRecordList[chatRecordList.length - 1].content = voice;

        // 生成语音完毕后自动调用播放语音
        const audioId = chatRecordList[chatRecordList.length - 1].id;
        handlePlayVoice(voice, audioId);
      });
    } catch (error) {
      console.error("播放音频失败:", error);
    }
  }
};

// 播放语音
const handlePlayVoice = (voice, id) => {
  // 如果正在播放其他音频，先停止
  if (currentAudioSource.value || currentAudioContext.value) {
    handleStopVoice();
    // 等待一小段时间确保资源释放
    setTimeout(() => {
      playNewAudio(voice, id);
    }, 100);
  } else {
    playNewAudio(voice, id);
  }
};

// 播放新音频的辅助函数
const playNewAudio = (voice, id) => {
  if (voice) {
    playingVoiceId.value = id;
    try {
      // 将Base64转换为ArrayBuffer
      const binaryString = atob(voice);
      const bytes = new Uint8Array(binaryString.length);
      for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
      }

      // 创建AudioContext并解码音频数据
      currentAudioContext.value = new (window.AudioContext ||
        window.webkitAudioContext)();
      currentAudioContext.value.decodeAudioData(bytes.buffer, (buffer) => {
        // 检查音频上下文是否仍然存在（可能已被用户停止）
        if (!currentAudioContext.value) {
          console.log("音频上下文已关闭，取消播放");
          return;
        }

        // 创建AudioSourceNode并播放音频
        currentAudioSource.value =
          currentAudioContext.value.createBufferSource();
        currentAudioSource.value.buffer = buffer;
        currentAudioSource.value.connect(currentAudioContext.value.destination);
        currentAudioSource.value.start(0);

        // 音频播放结束时调用handleStopVoice
        currentAudioSource.value.onended = () => {
          handleStopVoice();
        };
      });
    } catch (error) {
      console.error("播放音频失败:", error);
      playingVoiceId.value = "";
      // 确保在出错时也清理资源
      if (currentAudioContext.value) {
        currentAudioContext.value
          .close()
          .then(() => {
            currentAudioContext.value = null;
          })
          .catch((error) => {
            console.error("关闭音频上下文失败:", error);
            currentAudioContext.value = null;
          });
      }
      currentAudioSource.value = null;
    }
  }
};

const handleStopVoice = () => {
  console.log("停止播放");
  if (currentAudioSource.value) {
    // 停止音频源
    currentAudioSource.value.stop();
    currentAudioSource.value = null;
  }

  if (currentAudioContext.value) {
    // 关闭音频上下文
    currentAudioContext.value
      .close()
      .then(() => {
        currentAudioContext.value = null;
      })
      .catch((error) => {
        console.error("关闭音频上下文失败:", error);
        currentAudioContext.value = null;
      });
  }

  // 重置播放状态
  playingVoiceId.value = "";
};

// 快速提示
const handleQuickTips = (tips) => {
  userInput.value = tips;
  handleSendMessage();
};

// 清空对话记录
const handleClearChat = () => {
  // 弹出确认弹窗
  Modal.confirm({
    title: "确认清空对话记录吗？",
    okText: "确认",
    okType: "danger",
    onOk: () => {
      // 清空对话记录
      chatRecordList.length = 0;
      message.success("对话记录已清空！");
    },
    onCancel: () => {
      // 取消清空，不做任何操作
    },
  });
};

// 开始语音输入
const startVoiceInput = async () => {
  try {
    // 检查浏览器是否支持媒体设备
    if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
      console.error("当前浏览器不支持音频录制功能");
      message.error("当前浏览器不支持音频录制功能");
      // 可以添加错误提示
      return;
    }

    // 检查浏览器是否支持MediaRecorder
    if (!window.MediaRecorder) {
      console.error("当前浏览器不支持MediaRecorder API");
      message.error("当前浏览器不支持MediaRecorder API");
      // 可以添加错误提示
      return;
    }

    // 请求麦克风权限
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });

    // 初始化录音相关变量
    audioChunks.value = [];
    isRecording.value = true;

    // 创建MediaRecorder实例
    mediaRecorder.value = new MediaRecorder(stream);

    // 监听录音数据
    mediaRecorder.value.ondataavailable = (event) => {
      audioChunks.value.push(event.data);
    };

    // 监听录音结束
    mediaRecorder.value.onstop = async () => {
      // 创建音频Blob
      const audioBlob = new Blob(audioChunks.value, { type: "audio/wav" });

      // 创建FormData对象
      const formData = new FormData();
      formData.append("file", audioBlob, "recording.wav");

      try {
        // 调用语音转文字接口
        const response = await speechToText(chatModel.value.id, formData);

        // 将转换后的文本填入输入框
        if (response.data && response.data.text) {
          userInput.value = response.data.text;
        }
      } catch (error) {
        console.error("语音转文字失败:", error);
        // 可以添加错误提示
      } finally {
        // 关闭麦克风流
        stream.getTracks().forEach((track) => track.stop());
      }
    };

    // 开始录音
    mediaRecorder.value.start();
  } catch (error) {
    console.error("获取麦克风权限失败:", error);
    // 可以添加错误提示
  }
};

// 停止语音输入
const stopVoiceInput = () => {
  if (mediaRecorder.value && isRecording.value) {
    mediaRecorder.value.stop();
    isRecording.value = false;
  }
};

// 处理语音输入按钮点击
const handleVoiceInputClick = () => {
  // 确保在客户端环境中执行
  if (typeof window === "undefined" || typeof navigator === "undefined") {
    console.error("语音输入功能仅在客户端环境中可用");
    return;
  }

  if (isRecording.value) {
    stopVoiceInput();
  } else {
    startVoiceInput();
  }
};

// ------------ onMounted ------------
onMounted(() => {
  // 标记为客户端环境
  isClient.value = true;
  handleInit();
});
</script>

<style lang="scss" scoped>
$header-height: 60px;
// 我的对话
.my-chat-container {
  display: flex;

  // 侧边栏
  .side-bar-container {
    display: flex;
    flex-direction: column;
    width: 350px;
    height: calc(100vh - $header-height);
    background-color: #fcfcff;
    border: 1px solid #ececec;

    // 模型信息
    .model-info-wrapper {
      width: 100%;
      height: 350px;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 10px;
      border-bottom: 1px solid #ececec;
      padding: 40px;
      padding-bottom: 20px;
      // background-color: #fff;

      // 模型头像
      .model-avatar {
        width: 80px;
        height: 80px;
        border-radius: 50%;
        overflow: hidden;

        img {
          width: 100%;
          height: 100%;
          object-fit: cover;
        }
      }

      // 模型名称
      .model-name {
        font-size: 24px;
        line-height: 24px;
        font-weight: bold;
        width: 200px; /* 固定宽度 */
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        text-align: center;
      }
      
      // 中等长度的模型名称
      .model-name-medium {
        font-size: 20px;
      }
      
      // 长模型名称
      .model-name-long {
        font-size: 18px;
      }

      // 模型作者
      .model-author-wrapper {
        display: flex;
        align-items: center;
        gap: 5px;
        font-size: 14px;
        color: #999;

        // 作者头像
        .author-avatar {
          width: 20px;
          height: 20px;
          border-radius: 50%;
          overflow: hidden;
          img {
            width: 100%;
            height: 100%;
            object-fit: cover;
          }
        }
      }

      // 模型类型
      .model-tag-wrapper {
        display: flex;
        gap: 8px;
        font-size: 12px;
        color: #999;

        // 模型卡片标签项
        .tag-item {
          padding: 4px 8px;
          border-radius: 4px;
          color: #5147ff;
          background-color: #e4e7ff;
          cursor: pointer;
          transition: all 0.3s ease;

          &:hover {
            color: #4036ff;
            background-color: #d3d8ff;
          }
        }
      }

      // 模型描述
      .model-desc {
        font-size: 14px;
        color: #999;
        text-align: center;
        margin-top: 10px;
      }

      // 清空对话按钮
      .model-clear-btn {
        margin-top: auto;
      }
    }

    // 最近聊天模型列表
    .recent-model-list-wrapper {
      display: flex;
      flex-direction: column;
      width: 100%;
      height: 100%;
      overflow: hidden;

      // 最近聊天模型列表标题
      .recent-model-list-title {
        font-size: 16px;
        font-weight: bold;
        padding: 20px;
        padding-bottom: 10px;
      }

      // 最近聊天模型列表
      .recent-model-list {
        display: flex;
        flex-direction: column;
        gap: 10px;
        padding: 10px 20px;
        height: 100%;
        overflow-y: scroll;

        // 最近聊天模型列表项
        .recent-model-item {
          display: flex;
          align-items: center;
          gap: 10px;
          padding: 10px 16px;
          background-color: #fff;
          border: 1px solid #fff;
          cursor: pointer;
          transition: all 0.3s ease;
          border-radius: 8px;

          &:hover {
            // background-color: #fefefe;
            box-shadow: 0 0 10px #4096ff1a;
            border: 1px solid #4096ff;
            position: relative;
          }

          // 当前选中的模型项
          &.active {
            background-color: #e6f7ff;
            border: 1px solid #4096ff;
            box-shadow: 0 0 10px #4096ff1a;
          }

          // 最近聊天模型列表项头像
          .recent-model-avatar {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            overflow: hidden;

            img {
              width: 100%;
              height: 100%;
              object-fit: cover;
            }
          }

          // 最近聊天模型列表项名称
          .recent-model-name {
            font-size: 14px;
            font-weight: bold;
          }
        }
      }
    }
  }

  .my-chat-wrapper {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: calc(100vh - $header-height);
    position: relative;
  }

  // 对话区域（缺省）
  .no-chat-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 10px;
    padding: 20px;
    width: 100%;
    height: 100%;
    background-color: #fff;
    padding-bottom: 200px;

    // 缺省头像
    .no-chat-avatar {
      width: 120px;
      height: 120px;
      border-radius: 8px;
      overflow: hidden;

      img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }

    // 缺省名称
    .no-chat-name {
      font-size: 24px;
      font-weight: bold;
    }

    // 缺省描述
    .no-chat-desc {
      font-size: 14px;
      color: #666;
      text-align: center;
    }

    // 缺省问题
    .no-chat-question-wrapper {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      gap: 10px;
      padding: 10px;
      margin-top: 10px;

      // 缺省问题标题
      .no-chat-question-title {
        font-size: 14px;
        color: #1a1a11;
        text-align: center;
      }

      // 缺省问题项
      .no-chat-question-item {
        font-size: 14px;
        color: #333;
        background-color: #f0f0f0;
        padding: 10px 16px;
        border-radius: 6px;
        border-top-right-radius: 0;
        text-align: center;
        cursor: pointer;
        transition: all 0.3s ease;

        &:hover {
          background-color: #e5e5e5;
        }
      }
    }
  }

  // 对话区域
  .chat-container {
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 40px 300px;
    width: 100%;
    height: calc(100% - 160px);
    min-height: 1em;
    overflow-y: auto;

    &::before {
      content: "";
      position: absolute;
      bottom: 150px;
      left: 0px;
      right: 0px;
      width: 100%;
      height: 50px;
      background: linear-gradient(to top, #fff 0%, #ffffff00 100%);
      z-index: 10;
      transition: all 0.3s ease;
    }

    // 用户对话项
    .user-chat-item {
      display: flex;
      gap: 10px;
    }

    // 助手对话项
    .assistant-chat-item {
      display: flex;
      gap: 10px;

      .chat-content-wrapper .chat-content {
        background-color: #ebeced;
      }
    }

    // 对话项头像
    .chat-avatar {
      width: 36px;
      height: 36px;
      border-radius: 50%;
      overflow: hidden;
      flex-shrink: 0;

      img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }

    // 对话项名称
    .chat-name {
      font-size: 12px;
      color: #666;
    }

    // 对话项内容
    .chat-content-wrapper {
      display: flex;
      flex-direction: column;
      gap: 6px;

      // 对话项内容
      .chat-content {
        background-color: #d1e3ff;
        padding: 12px 16px;
        border-radius: 8px;
        font-size: 14px;
        line-height: 1.5em;
      }

      // 对话项语音
      .audio-wrapper {
        cursor: pointer;
        transition: all 0.3s ease;
        user-select: none;

        &:hover {
          opacity: 0.8;
        }

        .audio-img {
          width: 20px;
          height: 20px;
          color: #333;
          overflow: hidden;
          flex-shrink: 0;
          margin-right: 10px;
        }
      }
    }
  }

  // 用户输入框
  .user-input-container {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-end;
    gap: 10px;
    padding: 10px;
    width: 60%;
    min-height: 100px;
    margin: 50px auto;
    margin-top: auto;
    border: 1px solid #ddd;
    border-radius: 8px;
    background-color: #fff;
    transition: all 0.3s ease;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 100;

    &:hover {
      border: 1px solid #4096ff;
    }

    /* 当输入框聚焦时，修改父容器样式 */
    &:has(.ant-input:focus) {
      border: 1px solid #4096ff;
    }

    .ant-input {
      border: none;
      outline: none;
      resize: none;
      box-shadow: none;
      font-size: 14px;
      color: #333;
      background-color: transparent;
    }

    // 工具条
    .tools-bar-wrapper {
      display: flex;
      justify-content: flex-end;
      align-items: center;
      padding: 0 10px;
      gap: 10px;
    }
  }
}
</style>
